import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';

class SplashCacheManager {
  static String cachePictureName = "cache_image.jpg";
  static String cacheVideoName = "cache_video.mp4";
  static final SplashCacheManager _instance = SplashCacheManager._internal();
  factory SplashCacheManager() {
    return _instance;
  }
  SplashCacheManager._internal();

  //请求接口获取配置数据
  void getConfig() {
    //...
  }

  Future<Uint8List> downloadImage(String url) async {
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      return response.bodyBytes;
    } else {
      throw Exception('Failed to load image');
    }
  }

  Future<String> cacheImage(Uint8List imageData) async {
    final directory = await getTemporaryDirectory();
    final filePath = '${directory.path}/$cachePictureName';
    final file = File(filePath);
    await file.writeAsBytes(imageData);
    return filePath;
  }

  Future<File> getImage(String url) async {
    final cachedFilePath = await cacheImageFromUrl(url);
    return File(cachedFilePath);
  }

  Future<String> cacheImageFromUrl(String url) async {
    final cachedFilePath = await getCachedFilePath(url);
    if (await File(cachedFilePath).exists()) {
      return cachedFilePath;
    } else {
      final imageData = await downloadImage(url);
      return await cacheImage(imageData);
    }
  }

  Future<String> getCachedFilePath(String url) async {
    final hash = md5.convert(utf8.encode(url)).toString();
    final directory = await getTemporaryDirectory();
    return '${directory.path}/$cachePictureName'; //$hash.jpg';
  }

  // Video

  Future<Uint8List> downloadVideo(String url) async {
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      return response.bodyBytes;
    } else {
      throw Exception('Failed to download video');
    }
  }

  Future<String> cacheVideo(Uint8List videoData) async {
    final directory = await getTemporaryDirectory();
    final filePath = '${directory.path}/$cacheVideoName';
    final file = File(filePath);
    await file.writeAsBytes(videoData);
    return filePath;
  }

  Future<String> getCachedVideoPath(String url) async {
    // final hash = md5.convert(utf8.encode(url)).toString();
    final directory = await getTemporaryDirectory();
    return '${directory.path}/$cacheVideoName'; //$hash
  }

  Future<String> cacheVideoFromUrl(String url) async {
    final cachedVideoPath = await getCachedVideoPath(url);
    if (await File(cachedVideoPath).exists()) {
      return cachedVideoPath;
    } else {
      final videoData = await downloadVideo(url);
      return await cacheVideo(videoData);
    }
  }

  Future<File> getVideo(String url) async {
    final cachedVideoPath = await cacheVideoFromUrl(url);
    return File(cachedVideoPath);
  }

  Future<bool> cacheFileExist(String url, bool isVideo) async {
    final cachedPath =
        await (isVideo ? getCachedVideoPath(url) : getCachedFilePath(url));
    if (await File(cachedPath).exists()) {
      return true;
    } else {
      return false;
    }
  }
}
